﻿using System.Linq;
using TechnicalIndicators.Points;
using Utils;

namespace TechnicalIndicators.DateBased
{
	public class Trix : GeneratorBase<DatedSeriePoint, DatedSeriePoint>
	{
		#region Attributes

		private readonly ExponentialAverage _ema1;
		private readonly ExponentialAverage _ema2;
		private readonly ExponentialAverage _ema3;
		private readonly RatioOfChange _changeRatio;

		#endregion

		#region Public Methods

		public Trix()
		{
			_ema1 = new ExponentialAverage();
			_ema2 = new ExponentialAverage();
			_ema3 = new ExponentialAverage();
			_changeRatio = new RatioOfChange();
		}

		public Trix(ObservableCollection2<DatedSeriePoint> destination) : base(destination)
		{
			_ema1 = new ExponentialAverage();
			_ema2 = new ExponentialAverage();
			_ema3 = new ExponentialAverage();
			_changeRatio = new RatioOfChange();
		}

		public void Configure(int period)
		{
			_ema1.Source = this.Source;
			_ema2.Source = _ema1.Serie;
			_ema3.Source = _ema2.Serie;
			_changeRatio.Source = _ema3.Serie;	

			_ema1.Configure(period);
			_ema2.Configure(period);
			_ema3.Configure(period);
			_changeRatio.Configure(1, false); // This is fixed to  by indicator definition
		}

		public override void Start()
		{
			_ema1.Start();
			_ema2.Start();
			_ema3.Start();
			_changeRatio.Start();

			base.Start();
		}

		public override void Clear()
		{
			_ema1.Clear();
			_ema2.Clear();
			_ema3.Clear();
			_changeRatio.Clear();

			base.Clear();
		}

		protected override DatedSeriePoint CreatePoint(DatedSeriePoint sourcePoint)
		{
			DatedSeriePoint result = _changeRatio.Serie.GetReadLock().FirstOrDefault(point => point.X == sourcePoint.X);
			_changeRatio.Serie.FreeReadLock();
			return result;
		}

		#endregion
	}
}
